package model

import (
	"gowork/bidding/utils"
	"strconv"
	"time"
)

type Bidding struct {
	Id int64 `xorm:"pk autoincr"`
	Type int
	Name string
	InvitationCompanyNumber int
	BiddingCompanyNumber int
	QuotationCompanyNumber int
	DosageList []*Dosage `xorm:"-"`
	TebderAllocationList []*TebderAllocation `xorm:"-"`
	CutOffTime time.Time
	CreatedAt time.Time
	UpdatedAt time.Time
}

type BiddingDosage struct {
	Id int64 `xorm:"pk autoincr"`
	BiddingId int64
	DosageId int64
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Dosage struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Supplier struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	MatchingDegree string `xorm:"-"`
	DosageLsit []*Dosage `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type SupplierDosage struct {
	Id int64 `xorm:"pk autoincr"`
	SupplierId int64
	DosageId int64
	CreatedAt time.Time
	UpdatedAt time.Time
}

type TebderAllocation struct {
	Id int64 `xorm:"pk autoincr"`
	BiddingId int64
	SupplierId int64
	SupplierName string
	ResponseStatus int  // 1未响应  2已响应  3放弃响应  4响应超时
	ResponseTime time.Time
	DeadlineResponseTime time.Time
	ResponseRemark string
	ProofingStatus int  // 1未打样  2已打样  3放弃打样  4收到打样  5重新打样  6不要求重新打样  7打样超时
	SampleNumber string
	ProofingTime time.Time
	CutOffTime time.Time
	ProofingRemark string
	EvaluationStatus int  // 1未评测  2评测通过  3评测不通过
	EvaluationRemark string
	QuotationStatus int   // 1未邀请  2已邀请  3放弃报价  4已报价  5报价超时
	QuotationTime time.Time
	AsOfQuotationTime time.Time
	QuotationRemark string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Evaluating struct {
	Id int64 `xorm:"pk autoincr"`
	TebderAllocationId int64
	Results int
	AsOfQuotationTime time.Time
	FileUrlList string
	ReProofing bool
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (bidding *Bidding)Actions(taId int64)([]string, error){

	var ta TebderAllocation
	x.Id(taId).Get(&ta)

	var actionList []string

	if ta.ResponseStatus == 1{
		actionList = append(actionList, "【响应操作】", "【放弃响应操作】")
	}else if ta.ResponseStatus == 2 && ta.ProofingStatus == 1{
		actionList = append(actionList, "【打样操作】", "【放弃打样操作】")
	}else if (ta.ProofingStatus == 2 || ta.ProofingStatus == 5 || ta.ProofingStatus == 4 || ta.ProofingStatus == 6) && (ta.EvaluationStatus == 2 || ta.EvaluationStatus == 3){
		actionList = append(actionList, "【查看评测操作】")
		if ta.ProofingStatus == 5{
			actionList = append(actionList, "【重新打样操作】")
		}

		if ta.QuotationStatus == 2{
			actionList = append(actionList, "【报价操作】", "【放弃报价操作】")
		}else if ta.QuotationStatus == 4{
			actionList = append(actionList, "【报价操作】")
		}
	}else if ta.ProofingStatus == 4 && ta.EvaluationStatus == 1{
		if ta.QuotationStatus == 2{
			actionList = append(actionList, "【报价操作】", "【放弃报价操作】")
		}else if ta.QuotationStatus == 4{
			actionList = append(actionList, "【报价操作】")
		}
	}

	return actionList, nil
}

func (bidding *Bidding)ScmActions(taId int64)([]string, error){

	var ta TebderAllocation
	x.Id(taId).Get(&ta)

	var actionList []string

	if ta.ResponseStatus == 2 && ta.ProofingStatus == 2{
		actionList = append(actionList, "【收到打样操作】")
		if ta.EvaluationStatus == 2 || ta.EvaluationStatus == 3 {
			if ta.QuotationStatus == 1 {
				actionList = append(actionList, "【邀请报价操作】")
			}else if ta.QuotationStatus == 4{
				actionList = append(actionList, "【查看报价】")
			}
		}
	} else if ta.ResponseStatus == 2 && ta.ProofingStatus == 4{
		if ta.QuotationStatus == 1 {
			actionList = append(actionList, "【样品评测操作】", "【邀请报价操作】")
		}else if ta.QuotationStatus == 4{
			actionList = nil
			actionList = append(actionList, "【查看报价】")
		}
	} else if ta.ResponseStatus == 2 && (ta.ProofingStatus == 6 || ta.ProofingStatus == 5){
		if ta.QuotationStatus == 1 {
			actionList = append(actionList, "【邀请报价操作】")
		}else if ta.QuotationStatus == 4{
			actionList = nil
			actionList = append(actionList, "【查看报价】")
		}
	}

	return actionList, nil
}

func (bidding *Bidding)Operations(taId int64, o string, remark string, sampleNumber string)(map[string]interface{}, error){

	var ta TebderAllocation
	x.Id(taId).Get(&ta)

	var b Bidding
	x.Id(ta.BiddingId).Get(&b)

	if o == "1" { //响应
		ta.ResponseStatus = 2
		ta.ResponseRemark = remark
		ta.ResponseTime = time.Now()
		//ta.CutOffTime = time.Now().AddDate(0, 0, 1)

		b.BiddingCompanyNumber += 1
	}else if o == "2"{ //打样
		ta.ProofingStatus = 2
		ta.SampleNumber = sampleNumber
		ta.ProofingRemark = remark
		ta.ProofingTime = time.Now()
	}else if o == "3"{ //放弃打样
		ta.ProofingStatus = 3
		ta.ProofingRemark = remark
		ta.ProofingTime = time.Now()
	}else if o == "4"{ //收到打样
		ta.ProofingStatus = 4
	}else if o == "5"{ //重新打样
		ta.ProofingStatus = 2
		ta.SampleNumber = sampleNumber
		ta.ProofingRemark = remark
		ta.ProofingTime = time.Now()
	}else if o == "6"{ //邀请报价
		ta.QuotationStatus = 2
	}else if o == "7"{ //放弃响应
		ta.ResponseStatus = 3
		ta.ResponseRemark = remark
		ta.ResponseTime = time.Now()
	}else if o == "8"{ //放弃报价
		ta.QuotationStatus = 3
	}

	x.Id(taId).Update(&ta)

	x.Id(b.Id).Update(&b)

	return map[string]interface{}{"message":"成功","code":200}, nil
}

func (bidding *Bidding)SampleEvaluation(taId int64, e *Evaluating)(map[string]interface{}, error){

	w := new(utils.Worker)

	e.Id = w.GetId()
	e.TebderAllocationId = taId
	e.CreatedAt = time.Now()
	e.UpdatedAt = time.Now()
	x.Insert(e)

	var ta TebderAllocation
	ta.EvaluationStatus = e.Results
	ta.AsOfQuotationTime = e.AsOfQuotationTime

	if e.ReProofing == true{
		ta.ProofingStatus = 5
	}else {
		ta.ProofingStatus = 6
	}

	x.Id(taId).Update(&ta)

	return map[string]interface{}{"message":"成功","code":200}, nil
}

func (bidding *Bidding)Matching(bId int64)([]*Supplier, error){

	var b Bidding
	x.Id(bId).Get(&b)

	x.Join("INNER", "bidding_dosage", "bidding_dosage.dosage_id = dosage.id").Where("bidding_dosage.bidding_id = ?", bId).Find(&b.DosageList)

	var fsList []*Supplier
	x.Find(&fsList)

	var sList []*Supplier

	for _, fs := range fsList{

		var m float64

		x.Join("INNER", "supplier_dosage", "supplier_dosage.dosage_id = dosage.id").Where("supplier_dosage.supplier_id = ?", fs.Id).Find(&fs.DosageLsit)
		for _, sd := range fs.DosageLsit{
			for _, bd := range b.DosageList{
				if sd.Id == bd.Id {
					m += 1
				}
			}
		}

		if m > 0{
			fs.MatchingDegree = strconv.Itoa(int(m/4*100)) + "%"
			sList = append(sList, fs)
		}
	}

	return sList, nil
}

func (bidding *Bidding)Distribution(b *Bidding, sList []*Supplier)(map[string]interface{}, error){

	w := new(utils.Worker)

	for _, s := range sList{
		var ta = TebderAllocation{
			Id:   			   w.GetId(),
			BiddingId:         b.Id,
			SupplierId:        s.Id,
			SupplierName:      s.Name,
			ResponseStatus:    1,
			ResponseTime:      time.Time{},
			DeadlineResponseTime: time.Now().AddDate(0, 0, 1),
			ResponseRemark:    "",
			ProofingStatus:    1,
			ProofingTime:      time.Time{},
			CutOffTime:        b.CutOffTime,
			ProofingRemark:    "",
			EvaluationStatus:  1,
			EvaluationRemark:  "",
			QuotationStatus:   1,
			QuotationTime:     time.Time{},
			AsOfQuotationTime: time.Time{},
			QuotationRemark:   "",
			CreatedAt:         time.Now(),
			UpdatedAt:         time.Now(),
		}

		x.Insert(&ta)
	}

	b.InvitationCompanyNumber = len(sList)
	x.Id(b.Id).Update(b)

	return map[string]interface{}{"message":"成功","code":200}, nil
}

func (bidding *Bidding)TimeoutHandler(){

	var rtaList []*TebderAllocation
	x.SQL("select * from tebder_allocation where response_status = 1 and deadline_response_time <= ?", time.Now().Format("2006-01-02 15:04:05")).Find(&rtaList)
	//x.Where("response_status = ?", 1).And("deadline_response_time <= ", time.Now()).Find(&rtaList)
	for _, rta := range rtaList{
		rta.ResponseStatus = 4
		x.Id(rta.Id).Update(rta)
	}

	var ftaList []*TebderAllocation
	x.SQL("select * from tebder_allocation where proofing_status = 1 and response_status = 2 and cut_off_time <= ?", time.Now().Format("2006-01-02 15:04:05")).Find(&ftaList)
	for _, fta := range ftaList{
		fta.ProofingStatus = 7
		x.Id(fta.Id).Update(fta)
	}

	var qtaList []*TebderAllocation
	x.SQL("select * from tebder_allocation where quotation_status = 2 and as_of_quotation_time <= ?", time.Now().Format("2006-01-02 15:04:05")).Find(&qtaList)
	for _, qta := range qtaList{
		qta.QuotationStatus = 5
		x.Id(qta.Id).Update(qta)
	}
}